package com.harisucici.jetpackbase.base

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import java.util.*

/**
 * Created by harisucici on 2021/1/18
 * Class description:
 */

open class UnLastingLiveData<T>() : HBaseLiveData<T>() {


    public override fun setValue(value: T?) {
        super.setValue(value)
    }

    public override fun postValue(value: T) {
        super.postValue(value)
    }

    @Deprecated("不能这样用")
    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
    }


    @Deprecated("不能这样用")
    override fun observeForever(observer: Observer<in T?>) {
    }

    class Builder<T>() {
        private var isAllowNullValue = false
        fun setAllowNullValue(allowNullValue: Boolean): Builder<T> {
            isAllowNullValue = allowNullValue
            return this
        }

        fun create(): UnLastingLiveData<T> {
            val liveData: UnLastingLiveData<T> = UnLastingLiveData()
            liveData.isAllowNullValue = isAllowNullValue
            return liveData
        }
    }
}


open class HBaseLiveData<T> : LiveData<T>() {
    protected var isAllowNullValue = false
    private val observers = HashMap<Int, Boolean>()
    fun observeInActivity(activity: AppCompatActivity, observer: Observer<in T?>) {
        val owner: LifecycleOwner = activity
        val storeId = System.identityHashCode(activity.viewModelStore)
        observe(storeId, owner, observer)
    }

    fun observeInFragment(fragment: Fragment, observer: Observer<in T?>) {
        val owner = fragment.viewLifecycleOwner
        val storeId = System.identityHashCode(fragment.viewModelStore)
        observe(storeId, owner, observer)
    }

    private fun observe(
        storeId: Int,
        owner: LifecycleOwner,
        observer: Observer<in T?>
    ) {
        if (observers[storeId] == null) {
            observers[storeId] = true
        }
        super.observe(owner, Observer<T> { t: T? ->
            if (!observers[storeId]!!) {
                observers[storeId] = true
                if (t != null || isAllowNullValue) {
                    observer.onChanged(t)
                }
            }
        })
    }

    override fun setValue(value: T?) {
        if (value != null || isAllowNullValue) {
            for (entry in observers.entries) {
                entry.setValue(false)
            }
            super.setValue(value)
        }
    }

    fun clear() {
        super.setValue(null)
    }
}

